package com.ezops.dtcc;

import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardWatchEventKinds;
import java.nio.file.WatchEvent;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;

public class RegulatoryRunnable implements Runnable {
	private final Logger LOGGER = Logger.getLogger(RegulatoryRunnable.class);
	
	@SuppressWarnings("unused")
	private ApplicationContext context;
	private FpmlParser fpmlParser = null;
	private Properties props = null;
	
	public RegulatoryRunnable(Properties props, ApplicationContext context) {
		this.context = context;
		this.props = props;
		fpmlParser = (FpmlParser) context.getBean("fpmlParser");
	}

	public void run() {
		WatchService watcher = null;
		WatchKey watchKey = null;
		try {
			Path myDir = Paths.get(props.getProperty("FILE_WATCHER_PATH"));
			watcher = myDir.getFileSystem().newWatchService();
			myDir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE,
					StandardWatchEventKinds.ENTRY_DELETE,
					StandardWatchEventKinds.ENTRY_MODIFY);

			watchKey = watcher.take();
		} catch(Exception ex) {
			LOGGER.error("Error: " + ex.toString());
			return;
		}

		LOGGER.info("---Now watching "+props.getProperty("FILE_WATCHER_PATH")+"---");
		while(watchKey!=null) {
			try {
				File f = new File(props.getProperty("FILE_WATCHER_PATH")+"/"+props.getProperty("STOP_FILE_NAME"));
				if(f.exists() && !f.isDirectory()) {
					LOGGER.info("Quitting processing..");
					f.deleteOnExit();
					break;
				}

				List<WatchEvent<?>> events = watchKey.pollEvents();
				for (@SuppressWarnings("rawtypes") WatchEvent event : events) {
					if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) {
						LOGGER.info("New file dropped: "
								+ event.context().toString());
						String fullPath = props.getProperty("FILE_WATCHER_PATH")+"/"+event.context().toString();
						fpmlParser.readAndWrite(fullPath);
						archiveFile(event.context().toString());
					}
				}
				
				Thread.sleep(10000);
			} catch (Exception e) {
				LOGGER.error("Error: " + e.toString());
			}
		}
	}

	private boolean archiveFile(String filePath) {
		try {
			File processedFile = new File(props.getProperty("FILE_WATCHER_PATH")+"/"+filePath);
			File newFile = new File(props.getProperty("ARCHIVE_FILE_PATH")+"/"+filePath+"-"+Calendar.getInstance().getTimeInMillis());
			if (processedFile.renameTo(newFile)) {
				LOGGER.info(props.getProperty("FILE_WATCHER_PATH")+"/"+filePath+" move is successful..");
			}
		} catch (Exception e) {
			LOGGER.info(props.getProperty("FILE_WATCHER_PATH")+"/"+filePath+" move is unsuccessful..");
			return false;
		}
		return true;
	}
}
